package com.emc.atmos.test;


import java.security.MessageDigest;
import java.util.List;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.ws.rs.core.HttpHeaders;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import java.io.*;

import com.emc.atmos.test.messaging.AtmosRequestMessage;
//import com.sun.jersey.core.util.Base64;
//import com.sun.org.apache.xml.internal.security.utils.Base64;

public class AtmosAuth {
	private static Logger log = Logger.getLogger(AtmosAuth.class);
	
	/*
	 HashString is computed as follows:
	HTTPRequestMethod + '\n' +
	ContentType + '\n' +
	Range + '\n' +
	Date + '\n' +
	CanonicalizedResource + '\n' +
	CanonicalizedEMCHeaders
	where + is the concatenation operator.
	 */
	public Boolean authenticateRequest(AtmosRequestMessage msg) {
		log.info("authenticating request from user: " + msg.getHdrEMCUid());
		Boolean isValid = false;
		
		// get hash string from the request message
		String hashString = msg.getHashString();
		
		
		String sharedSecret = getSharedSecret(msg.getHdrEMCUid());
		
		String calculatedSignature = calculateSignature(hashString, sharedSecret);
		log.debug("calculated Signature: '" + calculatedSignature + "' - provided Signature: '" + msg.getHdrEMCSignature() + "'");
		
		// now see if our signature matches the one they sent
		
		if (calculatedSignature.equals(msg.getHdrEMCSignature())) {
			isValid = true;
			log.info("request passed authentication...");
		} else {
			log.info("request failed authentication...");
		}
		
		return isValid;
	}
	
	
	/**
	 * description: gets a shared secret for a given user
	 * @param userId
	 * @return
	 */
	public String getSharedSecret(String userId) {
		String sharedSecret = null;
		
		try {
			InputStream is = this.getClass().getClassLoader().getResourceAsStream("users.txt");
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			
			String line;
			while((line = br.readLine()) != null) {
				String[] fields = line.split("\\|");
				if (fields[0].equals(userId)) {
					sharedSecret = fields[1];
				}
			}
			
			if (sharedSecret == null) {
				log.error("user not found in users.txt");
			}
			
		} catch (Exception e) {
			log.error("error reading the users file.");
		}
		
		return sharedSecret;
	}
	
	
	/*
	 * calculate a signature from the shared secret and the hash string
	 * NOTE: you do not need to base64 encode your shared secret before you call this method
	 */
	public String calculateSignature(String hashString, String sharedSecret) {
		String calculatedSignature = "";
		
		/*
		 * signature = Base64(HMACSHA1(HashString))
		 */
		try {
			Mac mac = Mac.getInstance("HmacSHA1");
			Base64 b = new Base64();
		
			SecretKeySpec secret = 
						new SecretKeySpec(b.decode(sharedSecret.getBytes()), "HmacSHA1");
			mac.init(secret);
			byte[] digest = 
					mac.doFinal(hashString.getBytes("ISO-8859-1"));
			calculatedSignature = new String(b.encode(digest), "UTF-8");
			calculatedSignature=calculatedSignature.replace("\r\n", "");
		} catch (Exception e) {
			log.error("could not calculate signature...");
		}
		
	
		
		return calculatedSignature;
	}
	
	

	

}
